package com.bianguo.android.bprinter.view.widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.bianguo.android.baselibrary.utils.MLog;
import com.bianguo.android.bprinter.R;
import com.bianguo.android.bprinter.entity.ZoomBean;
import com.bianguo.android.bprinter.entity.ZoomBean2;
import com.bianguo.android.bprinter.utils.ScreenUtil;

public class ZoomView2 extends View {

    //点击了删除图标
    public static final int CLICK_POINT_TYPE_DELETE = 0;
    //点击了剪切图标
    public static final int CLICK_POINT_TYPE_CUT = 3;

    private ZoomBean2 zoomBean;
    private Paint mPaint;
    //用于提高canvas.drawBitmap的画质
    //因为在缩放的时候canvas.drawBitmap画质会降低
    private PaintFlagsDrawFilter pfd;
    private Bitmap mBitmap;
    private PointF centerPoint;
    private Matrix matrix;
    private float mLastX, mLastY;
    private float translateX, translateY;
    private boolean canTranslate, canScale, canRotate, singleScale;
    private float mScale, spacing;
    private float rotation, degree;
    private long clickTime;
    private boolean drawRect;
    private OnClickPointListener onClickPointListener;
    private OnFocusListener onFocusListener;
    private OnDoubleClickListener onDoubleClickListener;

    public ZoomView2(Context context) {
        this(context, null);
    }

    public ZoomView2(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ZoomView2(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs);
    }

    private void initView(Context context, AttributeSet attrs) {
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(2);
        mPaint.setColor(ActivityCompat.getColor(context, R.color.colorLine));
        //针对绘制bitmap添加抗锯齿
        mPaint.setFilterBitmap(true);

        pfd = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);

        matrix = new Matrix();
        zoomBean = new ZoomBean2(context, matrix);
        RectF mRect = new RectF();
        zoomBean.setRect(mRect);
    }

    public void addBitmap(Bitmap bitmap) {
        this.mBitmap = bitmap;
        zoomBean.setSrcBitmap(bitmap);
        postInvalidate();
        centerPoint = zoomBean.getCenterPoint();
    }

    public void updateBitmap(Bitmap bitmap) {
        PointF lastCenterPoint = zoomBean.getCenterPoint();
        this.mBitmap = bitmap;
        zoomBean.setSrcBitmap(bitmap);
        matrix.reset();
        postInvalidate();
        this.centerPoint = zoomBean.getCenterPoint();
        float translateX = lastCenterPoint.x - centerPoint.x;
        float translateY = lastCenterPoint.y - centerPoint.y;
        matrix.postTranslate(translateX, translateY);
        zoomBean.updatePoint(translateX, translateY);
//        this.centerPoint = zoomBean.getCenterPoint();
//        matrix.postRotate(rotation, this.centerPoint.x, this.centerPoint.y);
//        zoomBean.adjustLocation(matrix);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        centerPoint = zoomBean.getCenterPoint();
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                float preX = event.getX();
                float preY = event.getY();
                mLastX = preX;
                mLastY = preY;
                if (zoomBean.containsScale(preX, preY)) {
                    //单指缩放 和 旋转
                    singleScale = true;
                    canTranslate = false;
                    canScale = false;
                    canRotate = false;
                    drawRect = true;
                    float x = event.getX() - centerPoint.x;
                    float y = event.getY() - centerPoint.y;
                    spacing = (float) Math.sqrt(x * x + y * y);

                    double radians = Math.atan2(y, x);
                    degree = (float) Math.toDegrees(radians);

                    if (onFocusListener != null) {
                        onFocusListener.onFocus(this);
                    }
                } else if (zoomBean.containsMirror(preX, preY)) {
                    //单指在镜像图标上
                    canTranslate = false;
                    canScale = false;
                    singleScale = false;
                    canRotate = false;
                    drawRect = true;
                    clickTime = System.currentTimeMillis();
                    if (onFocusListener != null) {
                        onFocusListener.onFocus(this);
                    }
                } else if (zoomBean.containsDelete(preX, preY)) {
                    //单指在删除图标上
                    canTranslate = false;
                    canScale = false;
                    singleScale = false;
                    canRotate = false;
                    drawRect = true;
                    clickTime = System.currentTimeMillis();
                    if (onFocusListener != null) {
                        onFocusListener.onFocus(this);
                    }
                } else if (zoomBean.containsCut(preX, preY)) {
                    //单指在剪切图标上
                    canTranslate = false;
                    canScale = false;
                    singleScale = false;
                    canRotate = false;
                    drawRect = true;
                    clickTime = System.currentTimeMillis();
                    if (onFocusListener != null) {
                        onFocusListener.onFocus(this);
                    }
                } else {
                    //单指在整个View上，这个时候判断是否能单指滑动
                    singleScale = false;
                    canTranslate = zoomBean.contains(preX, preY);
                    canScale = false;
                    canRotate = false;
                    drawRect = canTranslate;
                    postInvalidate();
                    if (!canTranslate) {
                        clickTime = System.currentTimeMillis();
                        return super.onTouchEvent(event);
                    } else {
                        if (onFocusListener != null) {
                            onFocusListener.onFocus(this);
                        }
                    }
                }
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                if (canTranslate && event.getPointerCount() == 2) {
                    singleScale = false;
                    canTranslate = false;
                    canScale = true;
                    canRotate = true;
                    spacing = getSpacing(event);
                    degree = getDegree(event);
                }
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_MOVE:
                if (canTranslate) {
                    //单指移动
                    float moveX = event.getX();
                    float moveY = event.getY();

                    translateX = moveX - mLastX;
                    translateY = moveY - mLastY;
                    matrix.postTranslate(translateX, translateY);
                    mLastX = moveX;
                    mLastY = moveY;
                    zoomBean.updatePoint(translateX, translateY);

                    postInvalidate();
                }
                if (canScale) {
                    //双指缩放
                    float scale = getSpacing(event) / spacing;
                    matrix.postScale(scale, scale, centerPoint.x, centerPoint.y);
                    spacing = getSpacing(event);

//                    zoomBean.updatePoint(scale);
                    zoomBean.adjustLocation(matrix);
                    postInvalidate();
                }
                if (canRotate) {
                    //双指旋转操作
                    rotation = getDegree(event) - degree;
                    degree = getDegree(event);
                    if (rotation > 360) {
                        rotation = rotation - 360;
                    }
                    if (rotation < -360) {
                        rotation = rotation + 360;
                    }
                    matrix.postRotate(rotation, centerPoint.x, centerPoint.y);
//                    zoomBean.updatePoint(centerPoint, rotation);
                    zoomBean.adjustLocation(matrix);

                    postInvalidate();
                }
                if (singleScale) {
                    //单指缩放和旋转
                    float x = event.getX() - centerPoint.x;
                    float y = event.getY() - centerPoint.y;
                    float distance = (float) Math.sqrt(x * x + y * y);
                    float mScale = distance / spacing;
                    spacing = distance;
                    matrix.postScale(mScale, mScale, centerPoint.x, centerPoint.y);
//                    zoomBean.updatePoint(mScale);

                    //获取的角度为弧度
                    double radians = Math.atan2(y, x);
                    //弧度转化为度
                    float tempRotation = (float) Math.toDegrees(radians);
                    //要旋转的角度
                    rotation = tempRotation - degree;
                    //记录这次的角度，用于下次计算要旋转的角度
                    degree = tempRotation;
                    if (rotation > 360) {
                        rotation = rotation - 360;
                    }
                    if (rotation < -360) {
                        rotation = rotation + 360;
                    }
                    matrix.postRotate(rotation, centerPoint.x, centerPoint.y);
                    zoomBean.adjustLocation(matrix);

                    postInvalidate();
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
                canTranslate = false;
                canScale = false;
                singleScale = false;
                canRotate = false;
                getParent().requestDisallowInterceptTouchEvent(false);
                break;
            case MotionEvent.ACTION_UP:
                getParent().requestDisallowInterceptTouchEvent(false);
                canTranslate = false;
                canScale = false;
                singleScale = false;
                canRotate = false;
                float upX = event.getX();
                float upY = event.getY();
                if (zoomBean.containsMirror(upX, upY)) {
                    //点击了镜像图标按钮
                    if (System.currentTimeMillis() - clickTime <= 1000) {
                        matrix.postScale(-1, 1, centerPoint.x, centerPoint.y);
                        postInvalidate();
                    }
                } else if (zoomBean.containsDelete(upX, upY)) {
                    //点击了删除图标按钮
                    if (System.currentTimeMillis() - clickTime <= 1000) {
                        if (onClickPointListener != null) {
                            onClickPointListener.onClickPoint(this, CLICK_POINT_TYPE_DELETE);
                        }
                    }
                } else if (zoomBean.containsCut(upX, upY)) {
                    //点击了剪切图标
                    if (System.currentTimeMillis() - clickTime <= 1000) {
                        if (onClickPointListener != null) {
                            onClickPointListener.onClickPoint(this, CLICK_POINT_TYPE_CUT);
                        }
                    }
                } else if (!zoomBean.contains(upX, upY)) {
                    //点击了作用范围之外
                    if (System.currentTimeMillis() - clickTime <= 1000) {
                        MLog.mLog("点击了作用范围之外");
                    }
                } else if (zoomBean.contains(upX, upY)) {
                    long currentTimeMillis = System.currentTimeMillis();
                    if (currentTimeMillis - clickTime <= 300) {
                        if (onDoubleClickListener != null) {
                            onDoubleClickListener.onDoubleClick(this);
                        }
                    } else {
                        clickTime = currentTimeMillis;
                    }
                }
                requestLayout();
                break;
        }
        return true;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        setMeasuredDimension(getMeasure(widthMeasureSpec), getMeasure(heightMeasureSpec));
        int bottomY = getBottomY();
        int screenHeight = ScreenUtil.getScreenHeight(getContext());
        setMeasuredDimension(ScreenUtil.getScreenWidth(getContext()), bottomY > screenHeight ? bottomY : screenHeight);
    }

    private int getMeasure(int measureSpec) {
        int result = 0;
        int size = MeasureSpec.getSize(measureSpec);
        switch (MeasureSpec.getMode(measureSpec)) {
            //wrap_content
            case MeasureSpec.AT_MOST:
                break;
            //match_parent
            case MeasureSpec.EXACTLY:
                result = size;
                break;
        }
        return result;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mBitmap != null) {
            //对canvas设置抗锯齿的滤镜，防止变化canvas引起画质降低
            canvas.setDrawFilter(pfd);
            zoomBean.drawBitmap(canvas, mPaint);
        }
        if (drawRect) {
            zoomBean.drawRect(canvas, mPaint);
            zoomBean.drawPoint(canvas, mPaint);
        }
    }

    // 触碰两点间距离
    private float getSpacing(MotionEvent event) {
        //通过三角函数得到两点间的距离
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    // 取旋转角度
    private float getDegree(MotionEvent event) {
        //得到两个手指间的旋转角度
        double delta_x = event.getX(0) - event.getX(1);
        double delta_y = event.getY(0) - event.getY(1);
        double radians = Math.atan2(delta_y, delta_x);
        return (float) Math.toDegrees(radians);
    }

    // 旋转
    private float rotation(PointF p1, PointF p2) {
        double delta_x = (p1.x - p2.x);
        double delta_y = (p1.y - p2.y);
        double radians = Math.atan2(delta_y, delta_x);
        return (float) Math.toDegrees(radians);
    }

    public int getBottomY () {
        //加100是为了给底部留一点白，不然贴边了感觉怪怪的
        return (int) zoomBean.getBottomPoint().y + 100;
    }

    public void setOnClickPointListener(OnClickPointListener onClickPointListener) {
        this.onClickPointListener = onClickPointListener;
    }

    public void setOnFocusListener(OnFocusListener onFocusListener) {
        this.onFocusListener = onFocusListener;
    }

    public void setOnDoubleClickListener(OnDoubleClickListener onDoubleClickListener) {
        this.onDoubleClickListener = onDoubleClickListener;
    }

    public void postScale(float scale) {
        matrix.postScale(scale, scale, centerPoint.x, centerPoint.y);
        zoomBean.adjustLocation(matrix);
        zoomBean.translate2Dot(matrix);

        postInvalidate();
    }

    public void postTranslate(float dy) {
        matrix.postTranslate(0, dy);
        zoomBean.updatePoint(0, dy);
        postInvalidate();
    }

    public interface OnClickPointListener {
        void onClickPoint(View view, int pointType);
    }

    public interface OnFocusListener {
        void onFocus(View view);
    }

    public interface OnDoubleClickListener {
        void onDoubleClick(View view);
    }
}
